// Project name:JavaRedis
// Creator:muhong
// Date time:2023/2/7,5:29 下午
// Name:InternalThreadLocalMap

package org.gmh.util.internal;

import org.gmh.util.concurrent.FastThreadLocalThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

public class InternalThreadLocalMap extends UnpaddedInternalThreadLocalMap {

    private final static Logger logger = LoggerFactory.getLogger(InternalThreadLocalMap.class);

    private static final int DEFAULT_ARRAY_LIST_INITIAL_CAPACITY = 8;
    private static final int STRING_BUILD_INITIAL_SIZE;
    private static final int STRING_BUILD_MAX_SIZE;

    public static final Object UNSET = new Object();

    static {
        STRING_BUILD_INITIAL_SIZE = 1024;
        STRING_BUILD_MAX_SIZE = 1024;
    }

    public static InternalThreadLocalMap getIfSet() {
        Thread t = Thread.currentThread();
        if (t instanceof FastThreadLocalThread) {
            return ((FastThreadLocalThread) t).threadLocalMap();
        }
        return slowThreadLocalMap.get();
    }

    public static InternalThreadLocalMap get() {
        Thread thread = Thread.currentThread();
        if (thread instanceof FastThreadLocalThread) {
            return fastGet((FastThreadLocalThread) thread);
        } else {
            return slowGet();
        }

    }

    private static InternalThreadLocalMap fastGet(FastThreadLocalThread thread) {
        // 从环境变量去
        InternalThreadLocalMap threadLocalMap = thread.threadLocalMap();
        if (threadLocalMap == null) {
            thread.setThreadLocalMap(threadLocalMap = new InternalThreadLocalMap());
        }
        return threadLocalMap;
    }


    private static InternalThreadLocalMap slowGet() {
        // 从全局的map中取
        ThreadLocal<InternalThreadLocalMap> slowThreadLocalMap = UnpaddedInternalThreadLocalMap.slowThreadLocalMap;
        InternalThreadLocalMap ret = slowThreadLocalMap.get();
        if (ret == null) {
            ret = new InternalThreadLocalMap();
            slowThreadLocalMap.set(ret);
        }
        return ret;
    }

    public static void remove() {
        Thread t = Thread.currentThread();
        if (t instanceof FastThreadLocalThread) {
            ((FastThreadLocalThread) t).setThreadLocalMap(null);
        } else {
            slowThreadLocalMap.remove();
        }
    }

    public static void destroy() {
        slowThreadLocalMap.remove();
    }

    public static int nextVariableIndex() {
        int index = nextIndex.incrementAndGet();
        if (index < 0) {
            nextIndex.decrementAndGet();
            throw new IllegalStateException("too many thread-local indexed variables");
        }
        return index;
    }

    public static int lastVariableIndex() {
        return nextIndex.get() - 1;
    }

    // Cache line padding (must be public)  TODO 没有搞明白，先写吧
    // With CompressedOops enabled, an instance of this class should occupy at least 128 bytes.
    public long rp1, rp2, rp3, rp4, rp5, rp6, rp7, rp8, rp9;

    public InternalThreadLocalMap(){
        super(newIndexedVariableTable());
    }

    private static Object[] newIndexedVariableTable() {
        Object[] array = new Object[32];
        Arrays.fill(array, UNSET);
        return array;
    }

    public int size(){
        return 0;
    }
}
